
#include "../Main.h"

#include "../GL_Ext.h"

#include "RenderTarget.h"
#include "Visuals_Main.h"

FRIDGE_DECLARE_EXTERN_GL_EXTENSIONS

static GLenum g_axFBOBuf[] = { GL_COLOR_ATTACHMENT0 };

RenderTarget::RenderTarget( u_int uWidth, u_int uHeight )
{
	// TODO: Error checking

	m_uWidth = uWidth;
	m_uHeight = uHeight;

	// Color texture
	glGenTextures( 1, &m_uColorTexture );
	glBindTexture( GL_TEXTURE_2D, m_uColorTexture );
	glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP );
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, uWidth, uHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
	glBindTexture(GL_TEXTURE_2D, 0);

	// FBO
	glGenFramebuffers( 1, &m_uFBOHandle);
	glBindFramebuffer( GL_FRAMEBUFFER, m_uFBOHandle);

	// Create depth renderbuffer
	glGenRenderbuffers( 1, &m_uDepthRenderbuffer );
	glBindRenderbuffer(GL_RENDERBUFFER, m_uDepthRenderbuffer);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_uWidth, m_uHeight );
	glBindRenderbuffer(GL_RENDERBUFFER, 0);

	// Attach
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_uColorTexture, 0);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_uDepthRenderbuffer );

	// glCheckFramebufferStatus(GL_FRAMEBUFFER)
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

RenderTarget::~RenderTarget()
{
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
	// Textures
	glBindTexture(GL_TEXTURE_2D, 0);
	glDeleteTextures(1, &m_uColorTexture);
 	// RBO
	glDeleteRenderbuffers(1, &m_uDepthRenderbuffer);
 	// FBO
	glDeleteFramebuffers(1, &m_uFBOHandle);
}

void RenderTarget::Bind() const
{
	glBindTexture(GL_TEXTURE_2D, 0);
	glBindFramebuffer(GL_FRAMEBUFFER, m_uFBOHandle );
	glDrawBuffers( 1, g_axFBOBuf );
}

void RenderTarget::BindAsTexture() const
{
	glBindTexture(GL_TEXTURE_2D, m_uColorTexture );
}

void RenderTarget::UnBind() const
{
	// Just for completeness
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
}

void RenderTarget::FullWindowRender() const
{
	glViewport( 0, 0, m_uWidth, m_uHeight );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();
	glOrtho( -1.0f, 1.0f, -1.0f, 1.0f, -1, 1 );
	glEnable( GL_TEXTURE_2D );
	
	glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
	glBindTexture( GL_TEXTURE_2D, m_uColorTexture );
	glBegin( GL_QUADS );
	
		glTexCoord2f( 0.0f, 0.0f );
		glVertex2f( -1.0f, -1.0f );
		glTexCoord2f( 0.0f, 1.0f );
		glVertex2f( -1.0f, 1.0f );
		glTexCoord2f( 1.0f, 1.0f );
		glVertex2f( 1.0f, 1.0f );
		glTexCoord2f( 1.0f, 0.0f );
		glVertex2f( 1.0f, -1.0f );
	
	glEnd();
}